<?php

namespace App\Jobs\Wechat;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

use App\Models\Wechat\Record\Msg as ModelRecordMsg;
use App\Models\Wechat\Msg;
use App\Models\Attachment;
use EasyWeChat\Kernel\Http\StreamResponse;
use Log;
use Storage;

/**
 * 将微信消息记录表中的数据处理之后迁移到微信消息表
 * 将查询和添加分开,系统所有的查询基于微信消息表wechat_msg,而不是微信消息记录表
 */
class RecordMsg implements ShouldQueue
{
    public $tries = 2;

    public $timeout = 60;

    var $media ;
    var $recordMsg;

    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $msgs = ModelRecordMsg::where('isExecute',0)->limit(10)->get();
        $this->media = app('wechat.official_account')->media;

        foreach ($msgs as $msg) {
            $this->recordMsg = $msg;
            switch ($msg->msgType) {
                case 'image':
                    $this->executeImageFromUrl();
                    break;
                case 'text':
                    $this->executeText();
                    break;
                case 'voice':
                    $this->executeVoice();
                    break;
                case 'video':
                    $this->executeVideo();
                    break;
            }
        }

    }

    /**
     * 处理图片消息,图片的mediaId
     * @return [type] [description]
     */
    // function executeImage($msg){
    //     $error    = config('wechaterrorcode');
    //     $this->executeImageFromUrl($msg);
    //     try {
    //         $media = $this->media->get($msg->mediaId);

    //         $result = $media->save(public_path('upload/wechat/record/msg/image/'.$this->timePath));
    //         if(isset($result['errcode']) && $result['errcode']>0){
    //             Log::error('[微信][接收信息][下载]['.(array_key_exists($code,$error)==true ? $error[$code] : $result['errmsg']).']');
                
    //         }else{
    //             $this->execute($msg);
    //         }
    //     } catch (\Exception $e) {
    //         $code = $e->formattedResponse['errcode'];
    //         Log::error('[微信][接收信息][下载]['.(array_key_exists($code,$error)==true ? $error[$code] : $e->formattedResponse['errmsg']).']');
    //         $this->executeImageFromUrl($msg);
    //     }
    // }

    /**
     * 处理文本消息
     * @return [type] [description]
     */
    function executeText(){
        $msgUnique = $this->checkUniqueMsg($this->recordMsg);
        if(!$msgUnique){
            $this->insertMsg();
        }
        $this->execute();
    }

    /**
     * 处理图片消息,直接下载图片地址
     * @return [type] [description]
     */
    function executeImageFromUrl(){
        $msgUnique = $this->checkUniqueMsg();
        if(!$msgUnique){
            //上传附件库
            $attachment = new Attachment();
            $attachment->fileArea = 'wechats/record/msg/image/';
            $attachmentModel = $attachment->downloadPicUrl($this->recordMsg->mediaUrl,$this->recordMsg->mediaId);
            if(!$attachmentModel) return false;
            $this->insertMsg($attachmentModel);
        }
        $this->execute();
    }


    /**
     * 处理语音消息
     * @return [type] [description]
     */
    function executeVoice(){
        $msgUnique = $this->checkUniqueMsg();
        if(!$msgUnique){
            //接收语音
            $stream  = $this->executeWechatMedia(1,$this->recordMsg->mediaId);
            if(!$stream ){
                return false;
            }
            $attachment            = new Attachment();
            $fileArea  = 'wechats/record/msg/voice/';
            $attachment->url       = $attachment->rootName.$fileArea.$attachment->timePath;
            $attachment->remoteUrl = '';
            $attachment->fileType  = $this->recordMsg->mediaFormat;
            $attachment->fileName  = $this->recordMsg->mediaId.'.'.$this->recordMsg->mediaFormat;
            $attachment->fileSize  = 0;//文件大小不处理,在定时任务转换成wav格式后处理
            $attachment->isRemote  = 0;
            try {
                if(!Storage::makeDirectory($fileArea.$attachment->timePath)){
                    return false;
                }
                $result = $stream->save(public_path($attachment->url));
                $attachment->save();
                $this->insertMsg(null,$attachment);
            } catch (\Exception $e) {
                Log::error('[微信][接收信息][语音][下载]['.$e->formattedResponse['errmsg'].']');
                return false;
            }
        }
        $this->execute();
    }

    /**
     * 处理视频消息
     * @return [type] [description]
     */
    function executeVideo(){
        $msgUnique = $this->checkUniqueMsg();
        if(!$msgUnique){
            //接收视频
            $stream  = $this->executeWechatMedia(1,$this->recordMsg->mediaId);
            if(!$stream ){
                return false;
            }

        }
        $this->execute();
    }

    /**
     * 处理微信媒体消息
     * @return [type] [description]
     */
    function executeWechatMedia($type,$mediaId){
        $typeArr = [1=>'语音',2=>'视频'];
        $error    = config('wechaterrorcode');
        try {
            $stream  = $this->media->get($mediaId);
            if(isset($result['errcode']) && $result['errcode']>0){
                Log::error("[微信][接收信息][$typeArr[$type]][".(array_key_exists($result['errcode'],$error)==true ? $error[$result['errcode']] : $result['errmsg']).']');
                return false;
            }
        } catch (\Exception $e) {
            $code = $e->formattedResponse['errcode'];
            Log::error("[微信][接收信息][$typeArr[$type]][".(array_key_exists($code,$error)==true ? $error[$code] : $e->formattedResponse['errmsg']).']');
            return false;
        }
        return $stream ;
}

    

    /**
     * 将微信消息记录转移到微信消息表
     * @param  [type] $recordMsg [description]
     * @return [type]            [description]
     */
    function insertMsg($picAttachment=null,$voiceAttachment=null,$videoAttachment=null,$thumbVideoPicAttachment=null){
        $msg                       = new Msg();
        $msg->pic_attachment_id    = $picAttachment ? $picAttachment->id : 0;
        $msg->voice_attachment_id  = $voiceAttachment ? $voiceAttachment->id : 0;
        $msg->wechat_record_msg_id = $this->recordMsg->id;
        $msg->fromUserName         = $this->recordMsg->fromUserName;
        $msg->toUserName           = $this->recordMsg->toUserName;
        $msg->msgId                = $this->recordMsg->msgId;
        $msg->msgType              = $this->recordMsg->msgType;
        $msg->content              = $this->recordMsg->content;
        $msg->picUrl               = $picAttachment ? ($picAttachment->url.$picAttachment->fileName) : '';
        //语音消息不做地址处理,交给任务调度异步转换成非amr格式的文件,
        //之后再更新地址,更新的地址是转还后的文件地址,原文件保存,附件库不更新
        $msg->voiceUrl             = '';
        $msg->msgTime              = $this->recordMsg->created_at;
        $msg->save();
    }   

    /**
     * 更新消息记录已处理标记
     * @param  [type] $recordMsg [description]
     * @return [type]            [description]
     */
    function execute(){
        $this->recordMsg->isExecute = 1 ;
        $this->recordMsg->save();
    }

    /**
     * 验证微信消息记录在微信消息库中的唯一性,以防重复消息进入微信消息表
     * 
     * @param  [type] $recordMsg [description]
     * @return [type]            [description]
     */
    function checkUniqueMsg(){
        $msgUnique = Msg::where('wechat_record_msg_id',$this->recordMsg->id)->first();
        return $msgUnique;
    }
}
